package org.summerframework.component.upload.ftp.pool;

import org.summerframework.component.upload.ftp.FtpProperties;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;

import java.io.IOException;

/**
 * 链接创建
 */
class FtpConnectionFactory extends BasePooledObjectFactory<FTPClient> {
    private FtpProperties properties;

    FtpConnectionFactory(FtpProperties properties) {
        this.properties = properties;
    }

    @Override
    public FTPClient create() throws Exception {
        FTPClient ftp = null;
        try {
            ftp = new FTPClient();
            // 连接FPT服务器,设置IP及端口
            ftp.connect(properties.getService(), properties.getPort());
            // 设置用户名和密码
            ftp.login(properties.getAccount(), properties.getPassword());
            // 设置连接超时时间,5000毫秒
            ftp.setConnectTimeout((int) properties.getConnectTimeout().toMillis());
            // 设置中文编码集，防止中文乱码
            ftp.setControlEncoding("UTF-8");
            if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
                ftp.disconnect();
                throw new IllegalArgumentException("未连接到FTP，用户名或密码错误");
            }
            ftp.enterLocalPassiveMode();
        } catch (Exception e) {
            if (ftp != null) {
                ftp.disconnect();
            }
            throw e;
        }

        return ftp;
    }

    @Override
    public PooledObject<FTPClient> wrap(FTPClient ftpClient) {
        return new DefaultPooledObject<>(ftpClient);
    }

    @Override
    public void destroyObject(PooledObject<FTPClient> pooledObject) throws Exception {
        FTPClient ftpClient = pooledObject.getObject();

        try {
            if (ftpClient != null && ftpClient.isConnected()) {
                ftpClient.logout();
            }
        } catch (Exception e) {
            throw e;
        } finally {
            if (ftpClient != null) {
                ftpClient.disconnect();
            }
        }
    }

    @Override
    public boolean validateObject(PooledObject<FTPClient> p) {
        try {
            return p.getObject().sendNoOp();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return false;
    }
}
